package channels;


import javax.crypto.BadPaddingException;

import org.apache.log4j.Logger;
import org.bouncycastle.util.encoders.Base64;

import service.SecurityService;

public class AESChannel implements Channel {
	
	private TCPChannel tcpChannel;
	private static AESChannel instance;
	private SecurityService securityService;
	private static final Object singletonObject = new Object();
	private static final Logger log = Logger.getLogger(AESChannel.class);
	
	private AESChannel() {
		this.tcpChannel = TCPChannel.getInstance();
	}
	
	public AESChannel(TCPChannel tcpChannel) {
		this.tcpChannel = tcpChannel;
	}
	
	public static AESChannel getInstance() {
		if(instance == null) {
			synchronized(singletonObject) {
				if(instance == null) instance = new AESChannel();
			}
		}
		return instance;
	}
	
	
	@Override
	public boolean open(String hostname, int tcpport) {
		boolean boo = true;
		if(!tcpChannel.isOpen()) boo = tcpChannel.open(hostname, tcpport); 
		return boo;
	}

	@Override
	public void close() {
		tcpChannel.close();
	}

	@Override
	public void send(String message) {
		
		byte[] code = securityService.encryptMessageAES(message.getBytes());
		byte[] base64 = Base64.encode(code);
		// TODO Auto-generated method stub
		log.info("sending: "+message);
		tcpChannel.send(new String(base64));

	}

	@Override
	public String read() {
		String code = tcpChannel.read();
		//System.out.println("code vor b64 decode: "+code);
		byte[] message = null;
		if(code!=null) message = Base64.decode(code);
		//decode 
		// TODO Auto-generated method stub
		try {
			if(message != null) code = new String(securityService.decryptMessageAES(message));
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		log.info("reading: "+code);
		return code;
	}
	
	public void setSecurityService(SecurityService securityService) {
		this.securityService = securityService;
	}

	@Override
	public String getAddress() {
		return tcpChannel.getAddress();
	}

}
